package com.github.caiqy.shirodemo.core;

import com.github.pagehelper.PageInfo;
import lombok.Builder;
import lombok.Data;
import org.apache.ibatis.exceptions.TooManyResultsException;
import tk.mybatis.mapper.entity.Condition;
import tk.mybatis.mapper.entity.Example;

import java.util.Collection;
import java.util.List;

/**
 * @param <T>
 * @author caiqy
 */
public interface Service<T> {

    @Builder
    @Data
    class FieldValue{
        private String field;
        private Object value;
    }

    /**
     * 插入单个对象
     *
     * @param model 实体类
     * @return 插入数量
     */
    Integer insert(T model);

    /**
     * 插入列表
     *
     * @param models 实体类列表
     * @return 插入数量
     */
    Integer insertList(List<T> models);

    /**
     * @param id 通过主鍵刪除 @Return Integer
     */
    Integer deleteById(Object id);

    Integer deleteBy(String property, Object value);

    /**
     * @param ids 批量刪除 eg：ids -> “1,2,3,4” @Return Integer
     */
    Integer deleteByIds(String ids);

    /**
     * @param ids 批量刪除
     * @return
     */
    Integer deleteByIds(Iterable ids);

    /**
     * @param model 更新 @Return Integer
     */
    Integer update(T model);

    Integer updateByExampleSelective(T record, Example example);

    /**
     * @param id 通过ID查找 @Return T
     */
    T selectById(Object id);

    /**
     * @param fieldName javabean定义的属性名，不是数据库里的属性名
     * @param value     通过Model中某个成员变量名称（非数据表中column的名称）查找
     * @throws TooManyResultsException 通过Model中某个成员变量名称（非数据表中column的名称）查找,value需符合unique约束 @Return T
     */
    T selectBy(String fieldName, Object value) throws TooManyResultsException;

    /**
     * @param fieldName javabean定义的属性名，不是数据库里的属性名
     * @param value     通过Model中某个成员变量名称（非数据表中column的名称）查找
     */
    List<T> selectListBy(String fieldName, Object value);

    List<T> selectListIn(String fieldName, Collection<?> collection);

    List<T> selectListBy(FieldValue... fvs);

    /**
     * @param fieldName      javabean定义的属性名，不是数据库里的属性名
     * @param value          通过Model中某个成员变量名称（非数据表中column的名称）查找
     * @param ascProperties  升序数组
     * @param descProperties 降序数组
     * @return
     */
    List<T> selectAscDescListBy(String fieldName, Object value, List<String> ascProperties, List<String> descProperties);

    /**
     * @param fieldName      javabean定义的属性名，不是数据库里的属性名
     * @param value          通过Model中某个成员变量名称（非数据表中column的名称）查找
     * @param ascProperties  升序数组
     * @param descProperties 降序数组
     * @return
     */
    List<T> selectDescAscListBy(String fieldName, Object value, List<String> ascProperties, List<String> descProperties);

    /**
     * @param fieldName  javabean定义的属性名，不是数据库里的属性名
     * @param value      通过Model中某个成员变量名称（非数据表中column的名称）查找
     * @param properties 排序数组
     * @return
     */
    List<T> selectAscListBy(String fieldName, Object value, String... properties);

    /**
     * @param fieldName  javabean定义的属性名，不是数据库里的属性名
     * @param value      通过Model中某个成员变量名称（非数据表中column的名称）查找
     * @param properties 排序数组
     * @return
     */
    List<T> selectDescListBy(String fieldName, Object value, String... properties);


    int countBy(String fieldName, Object value);

    /**
     * @param ids 通过多个ID查找//eg：ids -> “1,2,3,4” @Return List<T>
     */
    List<T> selectListByIds(String ids);

    /**
     * @param ids 通过多个ID查找//eg：ids -> “1,2,3,4” @Return List<T>
     */
    List<T> selectListByIds(Iterable ids);

    /**
     * @param condition 根据条件查找 @Return List<T>
     */
    List<T> selectByCondition(Condition condition);

    /**
     * 根据条件进行分页查询
     *
     * @param condition
     * @param pageIndex
     * @param pageSize
     * @return
     */
    List<T> selectByCondition(Condition condition, int pageIndex, int pageSize);

    /**
     * @param example 根据条件查找 @Return List<T>
     */
    List<T> selectByExample(Example example);

    /**
     * 根据条件进行分页查询
     *
     * @param example
     * @param pageIndex
     * @param pageSize
     * @return
     */
    List<T> selectByExample(Example example, int pageIndex, int pageSize);

    /**
     * 获取所有 @Return List<T>
     */
    List<T> selectAll();

    /**
     * 分页获取数据
     *
     * @param pageIndex
     * @param pageSize
     * @return
     */
    PageInfo<T> selectAll(int pageIndex, int pageSize);

    /**
     * @param record
     * @return List<T>
     */
    List<T> select(T record);

    /**
     * 分页查询 根据实体中的属性值进行查询，查询条件使用等号
     *
     * @param record
     * @param pageIndex
     * @param pageSize
     * @return
     */
    PageInfo<T> select(T record, int pageIndex, int pageSize);

    /**
     * @param record
     * @return T 根据实体中的属性值进行查询，查询条件使用等号
     */
    T selectOne(T record);
}
